#include "wtlpch.h"

#include "resource.h"
#include "MainFrm.h"

#define TA_LEFTPAN_MIN_SIZE			200
#define TA_RIGHTTOP_DEF_PERCENT		40
#define TA_RIGHTDOWN_LEFT_MIN_SIZE	100

#define TA_ID_TRAY_MAIN_ICON		500

LRESULT CMainFrame::OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
	//Load TrayIcon
	m_hitIcon = CTrayNotifyIcon::LoadIcon(IDI_TRAYICON);
	m_tniTrayIcon.Create(this, TA_ID_TRAY_MAIN_ICON, TA_STR_APPLICATION_NAME, m_hitIcon, WM_TRAY_MESSAGE_ID, IDM_TRAY_CONTEXT);

	//Create a rebar to hold toolbars and lock it
	CreateSimpleReBar(ATL_SIMPLE_REBAR_NOBORDER_STYLE);
	m_rbRebar.Attach(m_hWndToolBar);

	//Create Toolbar and the container rebar
	HWND hWndToolBar = CreateSimpleToolBarCtrl(m_hWnd, IDR_MAINFRAME, FALSE, ATL_SIMPLE_TOOLBAR_PANE_STYLE);
	m_tbToolbar.Attach(hWndToolBar);
	AddSimpleReBarBand(hWndToolBar);

	//Create the Donwlist toolbar
	HWND hDownListToolBar = CreateSimpleToolBarCtrl(m_hWnd, IDT_DOWNLIST, FALSE, ATL_SIMPLE_TOOLBAR_PANE_STYLE);
	m_slvDownList.m_tbDownToolbar.Attach(hDownListToolBar);
	AddSimpleReBarBand(hDownListToolBar);

	//We Lock all toolbars
	m_rbRebar.LockBands(true);

	//For Frame window, create the status bar
	CreateSimpleStatusBar(IDS_TA_STATUSBAR_IDLEMSG);

	//Create the splitter window as the client window
	m_hWndClient = m_clientSplitter.Create(m_hWnd, rcDefault, NULL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN);
	m_clientSplitter.SetSplitterExtendedStyle(NULL);	//Set the Left panel do not resize with whole window
	m_clientSplitter.m_cxyMin = TA_LEFTPAN_MIN_SIZE;					//Set the left panel min size

	//Create the right Splitter
	m_rightSpliter.Create(m_clientSplitter, rcDefault, NULL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN);
	m_rightSpliter.SetSplitterExtendedStyle(NULL);

	//Create the rightdown splitter
	m_rightdownSpliter.Create(m_rightSpliter, rcDefault, NULL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN);
	m_rightdownSpliter.SetSplitterExtendedStyle(NULL);
	m_rightdownSpliter.m_cxyMin = TA_RIGHTDOWN_LEFT_MIN_SIZE;

	//Create the left tree window
	m_trTaskCatelog.Create(m_clientSplitter, rcDefault, NULL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | TVS_HASLINES | TVS_HASBUTTONS | TVS_SHOWSELALWAYS, WS_EX_CLIENTEDGE);
	m_trTaskCatelog.SetFont(AtlGetDefaultGuiFont());
	m_trTaskCatelog.AddCatItem();

	//Create the righttop downlist window, we assume a report list view
	m_slvDownList.Create(m_rightSpliter, rcDefault, NULL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | LVS_REPORT, WS_EX_CLIENTEDGE);
	m_slvDownList.InitColumnHeader();
	m_slvDownList.m_pDownInfoListView = &m_lvsFileInfo;
	m_slvDownList.m_hwndMainFrameWindow = m_hWnd;

	//Create the rightdown left thread list window
	m_trThreadOrFileInfo.Create(m_rightdownSpliter, rcDefault, NULL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | TVS_HASLINES | TVS_LINESATROOT | TVS_HASBUTTONS | TVS_SHOWSELALWAYS, WS_EX_CLIENTEDGE);
	m_trThreadOrFileInfo.SetFont(AtlGetDefaultGuiFont());

	//Create the rightdown right file info window
	m_lvsFileInfo.Create(m_rightdownSpliter, rcDefault, NULL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | LVS_REPORT, WS_EX_CLIENTEDGE);

	//Set the all splitter panel
	m_clientSplitter.SetSplitterPanes(m_trTaskCatelog, m_rightSpliter);
	m_rightSpliter.SetSplitterPanes(m_slvDownList, m_rightdownSpliter);
	m_rightdownSpliter.SetSplitterPanes(m_trThreadOrFileInfo, m_lvsFileInfo);

	//Caution, we have to Call UpdateLayout to cal the size of client, then the splitter window
	//could set its right size
	UpdateLayout();
	m_clientSplitter.SetSplitterPos(TA_LEFTPAN_MIN_SIZE);
	m_rightSpliter.SetSplitterPosPct(TA_RIGHTTOP_DEF_PERCENT);
	m_rightdownSpliter.SetSplitterPos(TA_RIGHTDOWN_LEFT_MIN_SIZE);


	UIAddToolBar(hWndToolBar);
	UISetCheck(ID_VIEW_TOOLBAR, true);
	UISetCheck(ID_VIEW_STATUS_BAR, true);
	UISetCheck(ID_VIEW_DOWNCAT, true);

	//For Tray Icon
	UISetCheck(ID_APP_SHOW_TAWINDOW, true);

	//Register object for message filtering and idle updates
	CMessageLoop* pLoop = _Module.GetMessageLoop();
	ATLASSERT(pLoop != NULL);

	//For MainFrame
	pLoop->AddMessageFilter(this);
	pLoop->AddIdleHandler(this);

	//For Downlist window idle processing
	pLoop->AddIdleHandler(&m_slvDownList);

	return 0;
}

LRESULT CMainFrame::OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
	if(wParam == SIZE_MINIMIZED)
	{
		ShowWindow(SW_HIDE);
		UISetCheck(ID_APP_SHOW_TAWINDOW, false);
		bHandled = true;
		return 0;
	}

	//We should pass it to the parent class to handle
	bHandled = FALSE;
	return 1;
}

LRESULT CMainFrame::OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
	// unregister message filtering and idle updates
	CMessageLoop* pLoop = _Module.GetMessageLoop();
	ATLASSERT(pLoop != NULL);
	pLoop->RemoveMessageFilter(this);
	pLoop->RemoveIdleHandler(this);

	bHandled = FALSE;
	return 1;
}

LRESULT CMainFrame::OnFileExit(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
{
	PostMessage(WM_CLOSE);
	return FALSE;
}

LRESULT CMainFrame::OnNewSniffer(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
{
	//We use do modal, so a temp instant is enough
	CSnifferURLDiag snifferDiag;
	CItemsCheckDiag	itemcheckDiag;

	snifferDiag.DoModal(*this);

	//Create Items List from sniffered data
	itemcheckDiag.CreateItemsList(snifferDiag.m_mapJSItems, snifferDiag.m_mapJSSecIp);

	//The User plant to do sniffer and checked some items
	if(itemcheckDiag.DoModal(*this) == IDOK && itemcheckDiag.m_vecSelectedItemList.size() != 0)
	{
		//First we offset the itemindex of existing items, cause we want to put the new items to top
		m_slvDownList.OffSetCurrentListItemIndex(itemcheckDiag.m_vecSelectedItemList.size());

		//Copy Selected items to download list, Add them to the top of the list
		INT nVecIndex = itemcheckDiag.m_vecSelectedItemList.size() - 1;
		for(; nVecIndex >= 0; nVecIndex--)
		{
			CMainDownListView::DOWN_LIST_ITEM itemDown;

			itemDown.fFileMBSize = itemcheckDiag.m_vecSelectedItemList[nVecIndex].fFileMBSize;
			itemDown.fFinishedMBSize = 0.0f;
			itemDown.uiLeftSec = 0;
			itemDown.wstrFileName = itemcheckDiag.m_vecSelectedItemList[nVecIndex].wstrFileName;
			itemDown.strURLRefer = itemcheckDiag.m_vecSelectedItemList[nVecIndex].strURLRefer;
			itemDown.wstrFileID = itemcheckDiag.m_vecSelectedItemList[nVecIndex].wstrFileID;
			itemDown.strSecIp = itemcheckDiag.m_vecSelectedItemList[nVecIndex].strSecIP;

			//ItemIndex
			itemDown.uiItemIndex = (UINT)nVecIndex;

			//Set Down Type for scheduled
			itemDown.itemType = CMainDownListView::DOWNLIST_SCHEDULE;

			//Push the item to the top
			m_slvDownList.m_lstDownListAll.push_front(itemDown);
		}

		//We Add New Items, so redraw the list
		m_slvDownList.RefreshDownList(CMainDownListView::DOWNLIST_SCHEDULE);

		//Began to sniffer download link
		m_slvDownList.SnifferScheduledItems();
	}

	return 0;
}

LRESULT CMainFrame::OnOptions(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
{
	CAppConfigDiag	optDiag;

	optDiag.DoModal(*this);

	return 0;
}

LRESULT CMainFrame::OnViewToolBar(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
{
	static BOOL bVisible = TRUE;	// initially visible
	bVisible = !bVisible;
	
	//Show Or Hide the rebar
	m_rbRebar.ShowWindow(bVisible ? SW_SHOWNOACTIVATE : SW_HIDE);

	UISetCheck(ID_VIEW_TOOLBAR, bVisible);
	UpdateLayout();
	return 0;
}

LRESULT CMainFrame::OnViewStatusBar(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
{
	BOOL bVisible = !::IsWindowVisible(m_hWndStatusBar);
	::ShowWindow(m_hWndStatusBar, bVisible ? SW_SHOWNOACTIVATE : SW_HIDE);
	UISetCheck(ID_VIEW_STATUS_BAR, bVisible);
	UpdateLayout();
	return 0;
}

LRESULT CMainFrame::OnViewDownCat(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
{
	bool bVisible = false;
	int nPMode = m_clientSplitter.GetSinglePaneMode();

	if(nPMode == SPLIT_PANE_NONE)
	{
		bVisible = true;
	}

	//Set Single Panel Mode
	m_clientSplitter.SetSinglePaneMode(bVisible ? SPLIT_PANE_RIGHT : SPLIT_PANE_NONE);

	UISetCheck(ID_VIEW_DOWNCAT, !bVisible);
	UpdateLayout();
	return 0;
}

LRESULT CMainFrame::OnAppAbout(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
{
	CAboutPropertySheets prSheet(IDS_TA_ABOUT_TITLE);

	prSheet.DoModal(*this);
	return 0;
}

LRESULT CMainFrame::OnShowWindow(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
{
	if(IsWindowVisible())
	{
		UISetCheck(ID_APP_SHOW_TAWINDOW, false);
		ShowWindow(SW_HIDE);
	}
	else
	{
		UISetCheck(ID_APP_SHOW_TAWINDOW, true);
		ShowWindow(SW_RESTORE);
	}

	return 0;
}

LRESULT CMainFrame::OnTrayNotification(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{

	//It's enough for NTray to handle it
	m_tniTrayIcon.OnTrayNotification(wParam, lParam);

	return 0;
}